﻿/*
    AAATripsManager contiene alcune utili funzioni per la creazione di viaggi.
    La classe utilizza AAANetUtils per interrogare, se necessario, il server di 
    loa o quello di google, al fine di recuperare le informazioni del caso per
    la creazione di viaggi.
*/
MapControl2.AAATripsManager = function(map)
{
    this._net = new MapControl2.AAANetUtils();
    this._gDir = new google.maps.Directions();
    this._routesCreated = null;
    this._routesNumber = 0;
    this._map = map;
};

MapControl2.AAATripsManager.prototype = {
    
    // -------------------- funzioni di creazione viaggi -----------------------------------
    // crea un viaggio che inizia in <from>, termina in <to>. Quando il viaggio
    // è stato correttamente creato, invoca <callback> passando come parametro 
    // il viaggio stesso.
    createTripA2B: function(from, to, waypoints, callback, vehicle)
    {
        var uniqueRoute = new Array();
        uniqueRoute.push(from);
        if (waypoints !== null)
        {
            for (i = 0; i < waypoints.length; i++)
            {
                uniqueRoute.push(waypoints[i]);
            }
        }
        uniqueRoute.push(to);
        var routes = new Array(uniqueRoute);
        this.createTrip(routes, callback, vehicle, false);
    },
    
    /* crea un viaggio dati due parametri:
       - routes: un array bidimensionale:
         routes[i] è la i-esima route
         il primo elemento di una route, ossia routes[i][0], è la località
         di partenza della route. L'ultimo elemento di una route è la località di partenza
         della successiva route, tranne nel caso dell'ultima route, ossia routes[n]. In questo 
         caso l'ultimo elemento è la fine del viaggio.
       - callback è la callback da richiamare passando il trip costruito.
    */
    createTrip: function(routes, callback, vehicle, areGeolocs)
    {
        var routesCreated = new Array();
        var currentRouteToCreate = 0, fun = null;
        if(areGeolocs)
            fun = this._createRouteFromGeolocs;
        else
            fun = this._createRoute;
        var routeCreationFunction = Function.createDelegate(this, fun);
        var m = this._map;
        
        // crea la prima route
        createRoute(vehicle);
        
        function createRoute(v)
        {
            // invoca la funzione di creazione della route passando l'array
            // di località che la identifica e la funzione di callback
            routeCreationFunction(routes[currentRouteToCreate], route_created, m, v);
        };
        
        function route_created(aaaRoute)
        {
            // registra la route creata
            routesCreated.push(aaaRoute);
            currentRouteToCreate++;
            
            if (currentRouteToCreate == routes.length)
            {
                // se non ci sono più route da creare si costruisce l'oggetto AAATrip
                // utilizzando l'apposita funzione statica e si invoca la callback 
                var trip = MapControl2.AAATrip.createTripFromAAARoutes(routesCreated, m);
                callback(trip);
            }else{
                // altrimenti si crea la successiva route
                createRoute(vehicle);
            }
        };
    },
    
    createTripFromGeolocs: function(geolocs, callback, vehicle){
        var a = new Array(), i=0;
        for (i=0; i<geolocs.length - 1; i++){
            a.push(geolocs.slice(i, i+2));
        }
        this.createTrip(a, callback, vehicle, true);
    },
    
    // recupera un viaggio dal server di loa. Il viaggio ha id <id>, è editabile
    // o meno a seconda del flag <isEditable>. <callback> sarà invocata quando
    // il viaggio sarà creato.
    createTripByID: function(id, isEditable, callback)
    {
        var thisContext = this;
        this._net.performRequest(MapControl2.AAANetUtils.GEOTRIP_REQUEST_BY_ID, id, resultContext, err_context);
        
        function resultContext(result)
        {
            thisContext.createTripByJson(result, isEditable, callback);   
        };
        
        function err_context(err)
        {
            google.maps.Event.trigger(thisContext._map, 'maperror', err);
        };
    },
    
    // crea un oggetto viaggio (AAATrip) dalla sua rappresentazione in json
    createTripByJson: function(jsonTrip, isEditable, callback)
    {
        var _tripFromServer = eval('('+jsonTrip+')');
        var _trip = new MapControl2.AAATrip(_tripFromServer, isEditable, this._map);
        callback(_trip);
    },
    
    createTripFromGeoTrip: function(geotrip, isEditable, callback)
    {
        var t = new MapControl2.AAATrip(geotrip, isEditable, this._map);
        callback(t);
    },
    // -----------------------------------------------------------------------------------
    
    // ---------------- private functions ------------------------------------------------
    // costruisce un oggetto AAARoute data una lista di stringhe
    // il primo punto è la località di partenza
    // l'ultimo punto è la località di arrivo
    // i punti intermedi sono waypoints
    // route_callback è una funzione da richiamare passando l'oggetto AAARoute creato
    _createRoute: function(route, route_callback, map, vehicle)
    {
        // fa il geocoding di tutte le località (start, stop e waypoint) in una botta sola
        this._net.performRequest
            (MapControl2.AAANetUtils.MULTIPLE_GEOCODING_REQUEST, route, 
                Function.createDelegate(this, geocodingResults), 
                Function.createDelegate(this, geocodingError), true);
        
        function geocodingResults(geolocs)
        {
            this._createRouteFromGeolocs(geolocs, route_callback, map, vehicle);
        };
        
        function geocodingError(error)
        {
            google.maps.Event.trigger(this._map, 'maperror', {type:'loa_error', err:error});
        };
    },
    
    _createRouteFromGeolocs: function(geolocs, route_callback, map, vehicle){
        // geolocs è il risultato della query: un array bidimensionale di GeoLoc
        // geolocs[i] = lista di GeoLoc associati alla località i
        // qui bisognerebbe far scegliere all'utente la località, per ora 
        // consideriamo la prima dell'array (che sarà sempre presente) come buona.
        var glatlng_points = new Array();
        var addresses = new Array();
        for(i = 0; i<geolocs.length; i++)
        {
            if (geolocs[i].length){
                glatlng_points.push(MapControl2.AAAUtils.toGLatLng(geolocs[i][0]));
                if (geolocs[i][0].Address)
                    addresses.push(geolocs[i][0].Address);
                else
                    addresses.push(geolocs[i][0].address);
            }else{
                glatlng_points.push(MapControl2.AAAUtils.toGLatLng(geolocs[i]));
                if (geolocs[i].Address)
                    addresses.push(geolocs[i].Address);
                else
                    addresses.push(geolocs[i].address);
            }
        }
        // una volta definiti i GLatLng associati a start, stop e waypoint
        // interroghiamo il server di google per reperire la GDirections associata
        this._net.performGoogleRequest(this._gDir, glatlng_points, 
            Function.createDelegate(this, gDirectionsLoaded),
            Function.createDelegate(this, gDirectionError));
        
        // una volta reperita la GDirections creiamo l'oggetto AAARoute
        // utilizzando l'apposita funzione statica
        function gDirectionsLoaded()
        {
            var aaaRoute = MapControl2.AAARoute.createRouteFromGDirections
                (addresses, glatlng_points, this._gDir, map, vehicle);
            route_callback(aaaRoute);
        };
        
        function gDirectionError()
        {     
            /*
            var aaaRoute = MapControl2.AAARoute.createRouteFromGDirections
                (route, glatlng_points, this._gDir, map, vehicle);
            route_callback(aaaRoute);
            */
        };
    }
    // ---------------------------------------------------------------------------
};

MapControl2.AAATripsManager.registerClass('MapControl2.AAATripsManager');
if (typeof(Sys) !== 'undefined') Sys.Application.notifyScriptLoaded();